//    Copyright (C) Kherty.  All rights reserved.
using System;
using System.Collections.Generic;
using System.Diagnostics.Contracts;
using System.Reflection;

namespace OpenLS.Spreadsheet
{
    internal static class CellHelper
    {
        public static object NormalizedValue(object value)
        {
            if (value is int)
            {
                return (double)(int)value;
            }
            if (value is Missing)
                return 0d;
            if (value is short)
            {
                return (double)(short)value;
            }
            if (value is float)
            {
                return (double)(float)value;
            }
            if (value is SingleCellRange)
                return (((SingleCellRange)value).Cell.Value);
            if (value is Range)
            {
                var r = (Range)value;
                if (r.Surface == 1)
                    return NormalizedValue(r.FirstCell);
                return Errors.ValueError;
            }
            if (value is IArray)
            {
                var array = (IArray)value;

                try
                {
                    return array[0, 0];
                }
                catch
                {
                    return Errors.ValueError;
                }
            }
            if (value is double)
                if (double.IsNaN((double)value))
                    return Errors.NumError;
            return value;
        }
        internal static bool IsDoubleValue(object value)
        {
            {
                return value is double || value is float || value is decimal || value is int;
            }
        }
        internal static double DoubleValue(object value)
        {
            {
                Contract.Requires(IsDoubleValue(value));
                object o = value;
                if (o is double)
                    return (double)o;
                if (o is float)
                    return (float)o;
                if (o is decimal)
                    return (double)(decimal)o;
                if (o is int)
                    return (int)o;
                throw new InvalidOperationException();
            }
        }

        public static IEnumerable<Cell> DistinctCells(IEnumerable<Cell> cells)
        {
            List<Cell>spanCells = new List<Cell>();
            foreach (var cell in cells)
            {
                if (cell.HasSpan)
                    spanCells.Add(cell);
                else
                {
                    yield return cell;
                }
            }
            foreach (var c in Enumerable.Distinct(spanCells))
                yield return c;
        }
    }
}